﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Lesson01_同步_服务端_Exercises2
{
    internal class ServerSocket
    {
        //服务端Socket
        public Socket socket;
        //客户端Socket
        Dictionary<int, ClientSocket> ClientDic = new Dictionary<int, ClientSocket>();
        private bool isClose;

        public void Start(string host, int port, int num)
        {
            isClose = false;
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(host), port);
                socket.Bind(ipPoint);
            }
            catch (Exception e)
            {
                Console.WriteLine("[ServerSocket][Start] Fail(Error:{0})", e.Message);
                return;
            }
            socket.Listen(num);
            ThreadPool.QueueUserWorkItem(Accept);
            ThreadPool.QueueUserWorkItem(Receive);
            Console.WriteLine("[ServerSocket][Start] {0}:{1} Success.", host, port);
        }

        public void Close()
        {
            if (socket == null)
                return;
            isClose = true;
            foreach (ClientSocket client in ClientDic.Values)
            {
                client.Close();
            }
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
            socket = null;
            Console.WriteLine("[ServerSocket][Close] Success.");
        }

        //接收连接
        private void Accept(object obj)
        {
            if (socket == null)
                return;
            while (!isClose)
            {
                try
                {
                    Console.WriteLine("开始监听连接...");
                    Socket clientSockt = socket.Accept();
                    ClientSocket client = new ClientSocket(clientSockt);
                    Console.WriteLine("客户端[{0}]连接...", clientSockt.RemoteEndPoint.ToString());
                    client.Send("欢迎来到三体世界!");
                    ClientDic.Add(client.ClientId, client);
                }
                catch (Exception e)
                {
                    Console.WriteLine("[ServerSocket][Accept] Fail(Error:{0})", e.Message);
                    return;
                }
            }
        }
        //接受消息
        private void Receive(object obj)
        {
            if (socket == null)
                return;
            while (!isClose)
            {
                if (ClientDic.Count == 0)
                    continue;
                foreach(ClientSocket client in ClientDic.Values)
                {
                    client.Receive();
                }
            }
        }

        public void Broadcast(string msg)
        {
            Console.WriteLine("广播消息:{0}", msg);
            if (socket == null)
                return;
            foreach (ClientSocket client in ClientDic.Values)
            {
                client.Send(msg);
            }
        }
    }
}
